"""
GT-LMS System Helper Functions
This module provides various utility functions used in the system
"""

import uuid
import hashlib
from datetime import datetime
from typing import Any, Dict, List


def generate_id(prefix: str = "") -> str:
    """
    Generate unique ID with optional prefix
    
    Args:
        prefix (str): Optional prefix for the ID
        
    Returns:
        str: Generated unique ID
    """
    unique_id = str(uuid.uuid4()).replace('-', '')[:12]
    if prefix:
        return f"{prefix}_{unique_id}"
    return unique_id


def format_datetime(dt: datetime = None, format_str: str = "%Y-%m-%d %H:%M:%S") -> str:
    """
    Format datetime to string
    
    Args:
        dt (datetime): Datetime to format. If None, use current time
        format_str (str): Format string
        
    Returns:
        str: Formatted datetime string
    """
    if dt is None:
        dt = datetime.now()
    return dt.strftime(format_str)


def calculate_gpa(grades: List[float]) -> float:
    """
    Calculate GPA from grade list (0-100 scale)
    
    Args:
        grades (List[float]): List of grades
        
    Returns:
        float: Calculated GPA (0.0-4.0 scale)
    """
    if not grades:
        return 0.0

    # Convert percentage grade to GPA (simplified conversion)
    total_points = 0.0
    for grade in grades:
        if grade >= 97:
            total_points += 4.0
        elif grade >= 93:
            total_points += 3.7
        elif grade >= 90:
            total_points += 3.3
        elif grade >= 87:
            total_points += 3.0
        elif grade >= 83:
            total_points += 2.7
        elif grade >= 80:
            total_points += 2.3
        elif grade >= 77:
            total_points += 2.0
        elif grade >= 73:
            total_points += 1.7
        elif grade >= 70:
            total_points += 1.3
        elif grade >= 67:
            total_points += 1.0
        elif grade >= 65:
            total_points += 0.7
        else:
            total_points += 0.0

    return round(total_points / len(grades), 2)


def convert_to_letter_grade(percentage: float) -> str:
    """
    Convert percentage grade to letter grade
    
    Args:
        percentage (float): Percentage grade (0-100)
        
    Returns:
        str: Letter grade
    """
    if percentage >= 97:
        return "A+"
    elif percentage >= 93:
        return "A"
    elif percentage >= 90:
        return "A-"
    elif percentage >= 87:
        return "B+"
    elif percentage >= 83:
        return "B"
    elif percentage >= 80:
        return "B-"
    elif percentage >= 77:
        return "C+"
    elif percentage >= 73:
        return "C"
    elif percentage >= 70:
        return "C-"
    elif percentage >= 67:
        return "D+"
    elif percentage >= 65:
        return "D"
    elif percentage >= 60:
        return "D-"
    else:
        return "F"


def hash_password(password: str) -> str:
    """
    Hash password using SHA-256
    
    Args:
        password (str): Password to hash
        
    Returns:
        str: Hashed password
    """
    return hashlib.sha256(password.encode()).hexdigest()


def verify_password(password: str, hashed: str) -> bool:
    """
    Verify password against hash
    
    Args:
        password (str): Password to verify
        hashed (str): Hashed password
        
    Returns:
        bool: True if password matches hash, False otherwise
    """
    return hash_password(password) == hashed


def sanitize_input(input_str: str) -> str:
    """
    Clean input string by removing potentially dangerous characters
    
    Args:
        input_str (str): Input string to clean
        
    Returns:
        str: Cleaned string
    """
    # Remove potentially dangerous characters
    dangerous_chars = ['<', '>', '&', '"', "'", ';', '--', '/*', '*/']
    sanitized = input_str
    for char in dangerous_chars:
        sanitized = sanitized.replace(char, '')
    return sanitized.strip()


def get_current_timestamp() -> int:
    """
    Get current timestamp (seconds)
    
    Returns:
        int: Current timestamp
    """
    return int(datetime.now().timestamp())